package io.renren.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.diagnosis.DiagnosisUtils;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import io.renren.common.utils.Result;
import io.renren.config.AliPayConfig;
import io.renren.dto.AliBusinessDTO;
import io.renren.service.AliBusinessService;
import io.renren.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName ApiAliPayController
 * @Description TODO
 * @Author Jll
 * @Date 2024/6/21 14:08
 * @Version 1.0
 */
@RestController
@RequestMapping("/api/ali")
@Slf4j
public class ApiAliPayController {

    @Resource
    private OrderService orderService;

    @Resource
    private AliBusinessService aliBusinessService;

    @Autowired
    private AliPayConfig aliPayConfig;
    //https://openapi.alipay.com/gateway.do     沙盒
    //https://openapi-sandbox.dl.alipaydev.com/gateway.do
    private static final String GATEWAY_URL = "https://openapi.alipay.com/gateway.do";

    private static final String FORMAT = "JSON";

    private static final String CHARSET = "UTF-8";

    private static final String SIGN_TYPE = "RSA2";


    @PostMapping("/alipayCallback")
    public Result payNotify(HttpServletRequest request, @RequestParam Map<String, String> params) throws Exception {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")){
            return new Result().error();
        }
        //将异步通知中收到的所有参数都存放到map中
        Map<String, String> requestParams = new HashMap<>(params);
        boolean signVerified = AlipaySignature.rsaCheckV1(requestParams, aliPayConfig.getPublicKey(), CHARSET, SIGN_TYPE); //调用SDK验证签名
        if(signVerified){
            // TODO 验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
            String tradeStatus = requestParams.get("trade_status");
            if ("TRADE_SUCCESS".equals(tradeStatus)) {
                // 执行订单支付成功后的逻辑
                // TODO: 更新订单状态、支付金额等
            }
            return new Result();
        }else{
            // TODO 验签失败则记录异常日志，并在response中返回failure.
            return new Result().error();
        }
    }





    /**
     * 代理扫码支付
     * @param orderNo
     * @return
     * @throws Exception
     */
    @GetMapping("/alipayAgent")
    public Result<Object> alipayAgent(@RequestParam String orderNo) throws Exception {
        AlipayClient alipayClient = new DefaultAlipayClient(
                GATEWAY_URL
                ,aliPayConfig.getAppId()
                ,aliPayConfig.getPrivateKey()
                ,FORMAT
                ,CHARSET
                ,aliPayConfig.getAliPublicKey()
                ,SIGN_TYPE);
        // 构造请求参数以调用接口
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        // 设置订单标题
        model.setSubject("支付手续费");
        // 设置产品码
//        product_code固定参数值枚举如下：
//        1、当面付 product_code：FACE_TO_FACE_PAYMENT；
//        2、APP支付 product_code：QUICK_MSECURITY_PAY；
//        3、手机网站支付 product_code：QUICK_WAP_WAY；
//        4、电脑网站支付 product_code：FAST_INSTANT_TRADE_PAY；
//        5、刷脸付 product_code：FACE_TO_FACE_PAYMENT（默认不传）；
//        6、新当面资金授权 product_code：PRE_AUTH_ONLINE；
//        7、JSAPI支付 product_code：JSAPI_PAY；
//        8、预授权支付 product_code：PREAUTH_PAY；
//        9、商家扣款 product_code：GENERAL_WITHHOLDING；
//        10、合并支付product_code：根据使用场景决定
//● QUICK_MSECURITY_PAY：APP场景alipay.trade.app.merge.pay（app 合并支付接口）请求使用。
//● QUICK_WAP_WAY：H5场景alipay.trade.wap.merge.pay（无线 Wap 合并支付接口 2.0） 请求使用。
//● JSAPI_PAY：小程序场景使用。
//        具体详见各个文档的参数说明示例。
        model.setProductCode("FACE_TO_FACE_PAYMENT");
        // 设置商户订单号
        model.setOutTradeNo(IdUtil.simpleUUID());
        // 设置订单总金额
        model.setTotalAmount("0.01");
        request.setBizModel(model);
        // 第三方代调用模式下请设置app_auth_token
        request.putOtherTextParam("app_auth_token", "202407BBb72dd60ce80442bcbddf1fc12840dX32");
        //回调地址
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        //request.setReturnUrl("https://www.baidu.com");
        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        System.out.println(response.getQrCode());
        System.out.println(response.getBody());
        if (response.isSuccess()) {
            System.out.println("调用成功");
            return new Result<>().ok(response.getQrCode());
        } else {
            System.out.println("调用失败");
            //sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            System.out.println(diagnosisUrl);
            return new Result<>().error();
        }
    }


    /**
     * 商家授权回调app_auth_code和第三方应用的 APPID
     * 然后去换取app_auth_token
     * @param
     * @return
     * @throws Exception
     */
    @GetMapping("/AliBusinessAuthorize")
    public void AliBusinessAuthorize(@RequestParam String appAuthCode) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(
                GATEWAY_URL
                ,aliPayConfig.getAppId()
                ,aliPayConfig.getPrivateKey()
                ,FORMAT
                ,CHARSET
                ,aliPayConfig.getAliPublicKey()
                ,SIGN_TYPE);
        AlipayOpenAuthTokenAppRequest request = new AlipayOpenAuthTokenAppRequest();
        JSONObject content = new JSONObject();
        content.set("grant_type", "authorization_code");
        content.set("code", appAuthCode);
        request.setBizContent(JSONUtil.toJsonStr(content));
        AlipayOpenAuthTokenAppResponse response = alipayClient.execute(request);
        if(response.isSuccess()){
            System.out.println("调用成功");
            //插入商家授权记录
            AliBusinessDTO aliBusinessDTO = new AliBusinessDTO();
            BeanUtil.copyProperties(response,aliBusinessDTO);
            aliBusinessService.save(aliBusinessDTO);
        } else {
            System.out.println("调用失败");
        }
    }

    /**
     * 订单查询
     * @param orderNo
     * @return
     * @throws AlipayApiException
     */
    @GetMapping("/alipayAgentQuery")
    public Result<Object> alipayAgentQuery(@RequestParam String orderNo) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(
                GATEWAY_URL
                , aliPayConfig.getAppId()
                , aliPayConfig.getPrivateKey()
                , FORMAT
                , CHARSET
                , aliPayConfig.getAliPublicKey()
                , SIGN_TYPE);
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setOutTradeNo(orderNo);
        request.setBizModel(model);
        // 第三方代调用模式下请设置app_auth_token
        request.putOtherTextParam("app_auth_token", "202407BBb72dd60ce80442bcbddf1fc12840dX32");
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {
            System.out.println("调用成功");
            return new Result<>().ok(JSONUtil.parseObj(response.getBody()));
        } else {
            System.out.println("调用失败");
            //sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            System.out.println(diagnosisUrl);
            return new Result<>().error();
        }
    }



}
